{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# Learning numba\n",
    "## First example\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.11 µs ± 12 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n",
      "23.5 µs ± 1.42 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "import numba\n",
    "from numba import jit\n",
    "import numpy as np\n",
    "x = np.arange(100).reshape(10, 10)\n",
    "def go_slow(a):\n",
    "    trace = 0.0\n",
    "    for i in range(a.shape[0]):   # Numba likes loops\n",
    "        trace += np.tanh(a[i, i]) # Numba likes NumPy functions\n",
    "    return a + trace              # Numba likes NumPy broadcasting\n",
    "\n",
    "# @jit(nopython=True) # Set \"nopython\" mode for best performance, equivalent to @njit\n",
    "# @jit(nopython=True, parallel=True, nogil=True, cache=True, inline='always')\n",
    "@jit(nopython=True, nogil=True, cache=True, inline='always')\n",
    "def go_fast(a): # Function is compiled to machine code when called the first time\n",
    "    # return go_slow(a)  # 错，不能被编译\n",
    "    trace = 0.0\n",
    "    for i in range(a.shape[0]):   # Numba likes loops\n",
    "        trace += np.tanh(a[i, i]) # Numba likes NumPy functions\n",
    "    return a + trace              # Numba likes NumPy broadcasting\n",
    "go_fast(x) # 先编译好\n",
    "%timeit go_fast(x)\n",
    "%timeit go_slow(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.21 µs ± 23.9 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n",
      "578 ns ± 15.5 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n",
      "204 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)\n",
      "6.15 ns ± 0.0838 ns per loop (mean ± std. dev. of 7 runs, 100,000,000 loops each)\n",
      "The slowest run took 13.67 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
      "4.77 µs ± 5.58 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "1.2 µs ± 10.8 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "x = np.arange(100).reshape(10, 10)\n",
    "@jit(nopython=True, nogil=True, cache=True, inline='always')\n",
    "def add(a, b):\n",
    "    return a+b\n",
    "\n",
    "# 正确方法\n",
    "add(x, x)\n",
    "%timeit add(x, x)\n",
    "%timeit x+x\n",
    "\n",
    "# 无效方法\n",
    "%timeit add(2, 3)\n",
    "%timeit 2+3\n",
    "\n",
    "\n",
    "# 可能有效方法\n",
    "%timeit add(2, x)\n",
    "%timeit 2+x"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\ir_utils.py:2152: NumbaPendingDeprecationWarning: \u001B[1m\n",
      "Encountered the use of a type that is scheduled for deprecation: type 'reflected list' found for argument 'x' of function 'list_add_fast'.\n",
      "\n",
      "For more information visit https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-reflection-for-list-and-set-types\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 4:\u001B[0m\n",
      "\u001B[1m@jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "\u001B[0m\u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(NumbaPendingDeprecationWarning(msg, loc=loc))\n",
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\ir_utils.py:2152: NumbaPendingDeprecationWarning: \u001B[1m\n",
      "Encountered the use of a type that is scheduled for deprecation: type 'reflected list' found for argument 'y' of function 'list_add_fast'.\n",
      "\n",
      "For more information visit https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-reflection-for-list-and-set-types\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 4:\u001B[0m\n",
      "\u001B[1m@jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "\u001B[0m\u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(NumbaPendingDeprecationWarning(msg, loc=loc))\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1m\n",
      "Compilation is falling back to object mode WITH looplifting enabled because Function list_add_fast failed at nopython mode lowering due to: \u001B[1mFailed in nopython mode pipeline (step: nopython frontend)\n",
      "\u001B[1m\u001B[1mNo conversion from list(int64)<iv=None> to reflected list(int64)<iv=None> for '$8return_value.3', defined at None\n",
      "\u001B[1m\n",
      "File \"F:\\Programs\\Python\\lib\\site-packages\\numba\\cpython\\listobj.py\", line 870:\u001B[0m\n",
      "\u001B[1m    def list_copy_impl(lst):\n",
      "\u001B[1m        return list(lst)\n",
      "\u001B[0m        \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "\u001B[0m\u001B[1mDuring: typing of assignment at F:\\Programs\\Python\\lib\\site-packages\\numba\\cpython\\listobj.py (870)\u001B[0m\n",
      "\u001B[1m\n",
      "File \"F:\\Programs\\Python\\lib\\site-packages\\numba\\cpython\\listobj.py\", line 870:\u001B[0m\n",
      "\u001B[1m    def list_copy_impl(lst):\n",
      "\u001B[1m        return list(lst)\n",
      "\u001B[0m        \u001B[1m^\u001B[0m\u001B[0m\n",
      "\n",
      "\u001B[0m\u001B[1mDuring: lowering \"z = call $4load_method.1(func=$4load_method.1, args=[], kws=(), vararg=None, target=None)\" at C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py (5)\u001B[0m\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1m\n",
      "Compilation is falling back to object mode WITHOUT looplifting enabled because Function \"list_add_fast\" failed type inference due to: \u001B[1m\u001B[1mCannot determine Numba type of <class 'numba.core.dispatcher.LiftedLoop'>\u001B[0m\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 6:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "    <source elided>\n",
      "    z = x.copy()\n",
      "\u001B[1m    for i, v in enumerate(y):\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\object_mode_passes.py:151: NumbaWarning: \u001B[1mFunction \"list_add_fast\" was compiled in object mode without forceobj=True, but has lifted loops.\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 5:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "\u001B[1m    z = x.copy()\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(errors.NumbaWarning(warn_msg,\n",
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\object_mode_passes.py:161: NumbaDeprecationWarning: \u001B[1m\n",
      "Fall-back from the nopython compilation path to the object mode compilation path has been detected, this is deprecated behaviour.\n",
      "\n",
      "For more information visit https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 5:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "\u001B[1m    z = x.copy()\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(errors.NumbaDeprecationWarning(msg,\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1mCode running in object mode won't allow parallel execution despite nogil=True.\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1mCannot cache compiled function \"list_add_fast\" as it uses lifted code\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1m\n",
      "Compilation is falling back to object mode WITHOUT looplifting enabled because Function \"list_add_fast\" failed type inference due to: \u001B[1m\u001B[1mnon-precise type pyobject\u001B[0m\n",
      "\u001B[0m\u001B[1mDuring: typing of argument at C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py (6)\u001B[0m\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 6:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "    <source elided>\n",
      "    z = x.copy()\n",
      "\u001B[1m    for i, v in enumerate(y):\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n",
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\object_mode_passes.py:151: NumbaWarning: \u001B[1mFunction \"list_add_fast\" was compiled in object mode without forceobj=True.\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 6:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "    <source elided>\n",
      "    z = x.copy()\n",
      "\u001B[1m    for i, v in enumerate(y):\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(errors.NumbaWarning(warn_msg,\n",
      "F:\\Programs\\Python\\lib\\site-packages\\numba\\core\\object_mode_passes.py:161: NumbaDeprecationWarning: \u001B[1m\n",
      "Fall-back from the nopython compilation path to the object mode compilation path has been detected, this is deprecated behaviour.\n",
      "\n",
      "For more information visit https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit\n",
      "\u001B[1m\n",
      "File \"C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py\", line 6:\u001B[0m\n",
      "\u001B[1mdef list_add_fast(x,y):\n",
      "    <source elided>\n",
      "    z = x.copy()\n",
      "\u001B[1m    for i, v in enumerate(y):\n",
      "\u001B[0m    \u001B[1m^\u001B[0m\u001B[0m\n",
      "\u001B[0m\n",
      "  warnings.warn(errors.NumbaDeprecationWarning(msg,\n",
      "C:\\Users\\YeCanming\\AppData\\Local\\Temp\\ipykernel_24984\\631882851.py:3: NumbaWarning: \u001B[1mCode running in object mode won't allow parallel execution despite nogil=True.\u001B[0m\n",
      "  @jit(nopython=False, nogil=True, cache=True, inline='always')\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "153 µs ± 2.01 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n",
      "65.9 µs ± 1.27 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n"
     ]
    }
   ],
   "source": [
    "a = list(range(1000))\n",
    "# @jit(nopython=True, nogil=True, cache=True, inline='always')\n",
    "@jit(nopython=False, nogil=True, cache=True, inline='always')\n",
    "def list_add_fast(x,y):\n",
    "    z = x.copy()\n",
    "    for i, v in enumerate(y):\n",
    "        z[i]+=v\n",
    "    return z\n",
    "def list_add_slow(x,y):\n",
    "    z = x.copy()\n",
    "    for i, v in enumerate(y):\n",
    "        z[i]+=v\n",
    "    return z\n",
    "list_add_fast(a,a)\n",
    "%timeit list_add_fast(a,a)\n",
    "%timeit list_add_slow(a,a)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## numba性能指南\n",
    "> note: 实践是检验真理的唯一标准。这里的只是理论上的。要用真实数据跑跑才知道快不快"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### loops"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "249 ms ± 27.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "187 ms ± 1.54 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "from numba import njit\n",
    "# @njit(cache = True)\n",
    "def ident_np(x):\n",
    "    return np.cos(x) ** 2 + np.sin(x) ** 2\n",
    "\n",
    "@njit(cache = True)\n",
    "def ident_loops(x):\n",
    "    r = np.empty_like(x)\n",
    "    n = len(x)\n",
    "    for i in range(n):\n",
    "        r[i] = np.cos(x[i]) ** 2 + np.sin(x[i]) ** 2\n",
    "    return r\n",
    "x = np.arange(1.e7)\n",
    "%timeit ident_np(x)\n",
    "%timeit ident_loops(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "note: 加速了还是比没加速好；numpy本来也有加速\n",
    "### Fastmath"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "21.6 ms ± 515 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "21.7 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "@njit(fastmath=False)\n",
    "def do_sum(A):\n",
    "    acc = 0.\n",
    "    # without fastmath, this loop must accumulate in strict order\n",
    "    for x in A:\n",
    "        acc += np.sqrt(x)\n",
    "    return acc\n",
    "\n",
    "@njit(fastmath=True)\n",
    "def do_sum_fast(A):\n",
    "    acc = 0.\n",
    "    # with fastmath, the reduction can be vectorized as floating point\n",
    "    # reassociation is permitted.\n",
    "    for x in A:\n",
    "        acc += np.sqrt(x)\n",
    "    return acc\n",
    "%timeit do_sum(x)\n",
    "%timeit do_sum_fast(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "区别不大\n",
    "\n",
    "### Parallel"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "188 ms ± 2.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
     ]
    }
   ],
   "source": [
    "@njit(parallel=True, nogil=True)\n",
    "def ident_parallel(x):\n",
    "    return np.cos(x) ** 2 + np.sin(x) ** 2\n",
    "%timeit ident_loops(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "也是区别不大"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5.7 ms ± 1.17 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "3.05 ms ± 239 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "#  out of order execution is valid\n",
    "from numba import prange\n",
    "@njit(parallel=True)\n",
    "def do_sum_parallel(A):\n",
    "    # each thread can accumulate its own partial sum, and then a cross\n",
    "    # thread reduction is performed to obtain the result to return\n",
    "    n = len(A)\n",
    "    acc = 0.\n",
    "    for i in prange(n):\n",
    "        acc += np.sqrt(A[i])\n",
    "    return acc\n",
    "\n",
    "@njit(parallel=True, fastmath=True)\n",
    "def do_sum_parallel_fast(A):\n",
    "    n = len(A)\n",
    "    acc = 0.\n",
    "    for i in prange(n):\n",
    "        acc += np.sqrt(A[i])\n",
    "    return acc\n",
    "%timeit do_sum_parallel(x)\n",
    "%timeit do_sum_parallel_fast(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "说明parallel对for loop 而不是np 加速更明显\n",
    "\n",
    "###"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.08 ms ± 57.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
      "6.38 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n",
      "2.8 ms ± 80.6 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'b' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
      "Input \u001B[1;32mIn [46]\u001B[0m, in \u001B[0;36m<cell line: 24>\u001B[1;34m()\u001B[0m\n\u001B[0;32m     22\u001B[0m get_ipython()\u001B[38;5;241m.\u001B[39mrun_line_magic(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mtimeit\u001B[39m\u001B[38;5;124m'\u001B[39m, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mb = do_norm_fast(x)\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m     23\u001B[0m get_ipython()\u001B[38;5;241m.\u001B[39mrun_line_magic(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mtimeit\u001B[39m\u001B[38;5;124m'\u001B[39m, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mc = do_norm_list(x)\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[1;32m---> 24\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124ma=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00ma\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m, b=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mb\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m, c=\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mc\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n",
      "\u001B[1;31mNameError\u001B[0m: name 'b' is not defined"
     ]
    }
   ],
   "source": [
    "import scipy\n",
    "def do_norm(x):\n",
    "    return np.linalg.norm(x)\n",
    "@njit(cache=True, fastmath=True)\n",
    "def do_norm_fast(x):\n",
    "    return np.linalg.norm(x)\n",
    "@njit(cache=True, parallel = True, fastmath=True)\n",
    "def do_norm_list(x):\n",
    "    n = len(x)\n",
    "    acc = 0.\n",
    "    for i in prange(n):\n",
    "        acc += np.square(x[i])\n",
    "    return np.sqrt(acc)\n",
    "def do_norm_slow(x):\n",
    "    n = len(x)\n",
    "    acc = 0.\n",
    "    for i in prange(n):\n",
    "        acc += np.square(x[i])\n",
    "    return np.sqrt(acc)\n",
    "x = np.arange(1.e7)\n",
    "%timeit a = do_norm(x)\n",
    "%timeit b = do_norm_fast(x)\n",
    "%timeit c = do_norm_list(x)\n",
    "# print(f\"a={a}, b={b}, c={c}\")\n",
    "# %timeit do_norm_slow(x)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}